package net.gdface.sdk.fse;

import net.gdface.utils.SampleLog;

/**
 * 特征码内存搜索引擎(FSE,feature search engine)java接口类(JNI)<br>
 * 提供高速实时的人脸特征相似度比对搜索/排序,支持多线程并行搜索<br>
 * 子类负责加载动态库<br>
 * <b>NOTE:</b>加载动态库后,必须首先初始化方法{@link #init(int, int, float, int)}进行初始化，才能调用其他native方法
 * @author guyadong
 *
 */
class FseJniBridge {
	public static final int DEFAULT_INITIAL_CAPACITY=1024*1024*16;
	public static final float DEFAULT_LOAD_FACTOR=  0.75F;
	public static final int DEFAULT_OVERBLOCK_CAPACITY=1024;
	public static final int DEFAULT_MODE=0;
	/**
	 * 动态库是否加载标志<br>
	 * 子类在成功加载动态库后，须将此标志置为true
	 */
	protected static boolean libraryLoaded = false;
	static{
		// add hook for release JNI resource on JVM shutdown 
		Runtime.getRuntime().addShutdownHook(new Thread (){
			@Override
			public void run() {
				if(libraryLoaded){
					SampleLog.log("release codemgr JNI resoure...");
					release();
					SampleLog.log("release codemgr JNI resoure finished");
				}
			}});
	}
	protected FseJniBridge(){

	}
	
	/**
	 * JNI接口初始化
	 * @param mode 指定运行模式(opencl,sse),默认为0(自动识别)
	 * @param initCapacity 内存表初始化容量
	 * @param loadFactor   内存表扩容因子
	 * @param overBlockCapacity  过载表容量
	 */
	public static native void init(int mode, int initCapacity, float loadFactor, int overBlockCapacity);
	/**
	 * 释放所有资源
	 */
	public static native void release();
	/**
	 * 	在内存表中根据比对相似度进行特征码搜索
	 * @param code 要比对的特征码
	 * @param sim 相似度阀值
	 * @param rows  最大返回的记录数
	 * @param imgMD5Set 比对的图片范围
	 * @return 返回包含相似度(降序)的结果数组,如果没有查到匹配的记录则返回空数组
	 */
	public static native CodeBean[] searchCode(byte[] code, double sim, int rows, String[] imgMD5Set);
	/**
	 * 根据特征码ID在表中查找指定的记录
	 * @param id 特征码ID,为{@code null}时抛出{@link IllegalArgumentException}
	 * @return 没有找到则返回空数组
	 */
	public static native CodeBean getFeature(byte[] id);

	/**
	 * 添加一条特征码到内存表<br>
	 * 输入参数{@code id, code}为{@code null}时抛出{@link IllegalArgumentException}
	 * @param id 特征码ID(MD5校验码)
	 * @param code 特征码字节数组
	 * @param imgMD5 特征码所在图像的MD5校验码,可为{@code null}
	 * @return 添加成功返回true, 否则返回false
	 */
	public static native boolean addFeature(byte[] id,byte[]code,String imgMD5);
	/**
	 * 根据特征码ID中表中删除指定的记录
	 * @param id 特征码MD5校验码
	 * @return 成功删除则返回true,否则返回false
	 */
	public static native boolean removeFeature(byte[] id);

	/**
	 * 
	 * @return 内存表中元素个数
	 */
	public static native int size();
	/**
	 * @return 哈希表统计信息(用于debug测试)
	 */
	public static native String statInfo();
}
